package Test;

import static org.junit.Assert.*;
import interfaces.ErrorReport;
import interfaces.ScriptDumper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import Pointers.OffsetRangeGenerator;
import Pointers.JPointerFactory.PointerType;
import Script.JScriptDumper;
import Script.JTableFile;
import Script.Offset;


/**
 * Tests:
 * 
 * 	- Can dump between two offsets, no pointers
 * 	- Dumps the text between the start offset and the first pointer
 * 	- Dumps text starting at textblock A and ending in B
 *  - Dumps the text between the last pointer and the stop offset 
 * 	  despite being outside block
 * 	- Dumps pointers from block B despite that text starts at A
 *  - Dumps a newline after an <end> tag
 *  - Does not dump pointer that point outside the start/stop values
 *  	* Assumes an exclusive stop value
 *  	* Needs to take text block into consideration
 *  - Can dump two pointers next to eachother
 *  - Can dump 0 bytes
 *  - Can insert <begin script> tag
 *  
 *  - Can handle illegal arguments (null)
 *  
 *  
 *  NOTE: Some tests add a linebreak at the end, simply
 *  because the read function does this when parsing an empty
 *  file line in the dumped script.
 * 
 * @author Tobias Edin
 *
 */
public class JScriptDumperTest {
	private String separator;
	private String filePath;
	
	@Before
	public void setup() {
		separator = System.getProperty("line.separator");
		filePath = "testFiles/testScript.txt";
		
		File script = new File(filePath);
		
		if (script.exists()) {
			if (!script.delete()) {
				System.out.println("Script file was found prior to test start, but could not be deleted.");
			}
		}
	}
	
	@Test
	public void canDumpBetweenTwoOffsets() throws IOException {
		File gamefile = new File("testFiles/gameTest/file1.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48); //0030
		Offset 	textStop = 		new Offset(87); //0056
		long 	header = 		10;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "A line of text<LINE>" + separator +
								"A second line.<END>" + separator +
								"New text." + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	@Test
	public void canDumpBetweenTwoOffsetsWithPointers() throws IOException {
		File gamefile = new File("testFiles/gameTest/file1.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets;
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping text parameters. */
		Offset 	textStart = 	new Offset(48); //0030
		Offset 	textStop = 		new Offset(88); //0057
		long 	header = 		10;
		long	textBlock =		0;
		
		/* Dumping pointer parameters */
		Offset pStart = new Offset(14); // 0E
		Offset pStop = new Offset(18); // 11
		OffsetRangeGenerator gen = new OffsetRangeGenerator(pStart, pStop, 2, 0);
		PointerType pType = PointerType._2Byte_littleEndian;
		pOffsets = gen.getOffsets();
		
		String expectedResult = "<PT0001>A line of text<LINE>" + separator +
								"A second line.<END>" + separator +
								"<PT0002>New text.<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void dumpsBetweenStartOffsetAndFirstPointerInSameBlock() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file1.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets;
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping text parameters. */
		Offset 	textStart = 	new Offset(48); //0030
		Offset 	textStop = 		new Offset(88); //0057
		long 	header = 		10;
		long	textBlock =		0;
		
		/* Dumping pointer parameters */
		Offset pStart = new Offset(16); // 10
		Offset pStop = new Offset(18); // 12
		OffsetRangeGenerator gen = new OffsetRangeGenerator(pStart, pStop, 2, 0);
		PointerType pType = PointerType._2Byte_littleEndian;
		pOffsets = gen.getOffsets();
		
		String expectedResult = "A line of text<LINE>" + separator +
								"A second line.<END>" + separator +
								"<PT0001>New text.<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void dumpsTextInBlockAThatEndsInBlockB() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file2.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping text parameters. */
		Offset 	textStart = 	new Offset(12582896); //BFFFF0
		Offset 	textStop = 		new Offset(12582932); //C00014
		long 	header = 		0;
		long	textBlock =		0; // No pointers used
		
		/* Dumping pointer parameters */
		PointerType pType = PointerType._2Byte_littleEndian;

		
		String expectedResult = "A line of text.<END>" + separator +
								"Text1<END>" + separator +
								"Text2<LINE>" + separator + "<END>" + separator +
								"Text3.<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	@Test
	public void dumpsTextbetweenLastPointerAndStopOffsetDespiteBeingInAnotherBlock() throws IOException {
		File gamefile = new File("testFiles/gameTest/file2.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets;
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping text parameters. */
		Offset 	textStart = 	new Offset(12582896); //BFFFF0
		Offset 	textStop = 		new Offset(12582932); //C00014
		long 	header = 		0;
		long	textBlock =		12517376; // BF0000
		
		/* Dumping pointer parameters */
		Offset pStart = new Offset(0); // 00
		Offset pStop = new Offset(2); // 02
		OffsetRangeGenerator gen = new OffsetRangeGenerator(pStart, pStop, 2, 0);
		PointerType pType = PointerType._2Byte_littleEndian;
		pOffsets = gen.getOffsets();
		
		String expectedResult = "<PT0001>A line of text.<END>" + separator +
								"Text1<END>" + separator +
								"Text2<LINE>" + separator + "<END>" + separator +
								"Text3.<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void dumpsPointersFromBlockBDespiteTextStartingInBlockA() throws IOException {
		File gamefile = new File("testFiles/gameTest/file2.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets;
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping text parameters. */
		Offset 	textStart = 	new Offset(12582896); //BFFFF0
		Offset 	textStop = 		new Offset(12582932); //C00014
		long 	header = 		0;
		long	textBlock =		12582912; // BF0000
		
		/* Dumping pointer parameters */
		Offset pStart = new Offset(2); // 02
		Offset pStop = new Offset(8); // 08
		OffsetRangeGenerator gen = new OffsetRangeGenerator(pStart, pStop, 2, 0);
		PointerType pType = PointerType._2Byte_littleEndian;
		pOffsets = gen.getOffsets();
		
		String expectedResult = "A line of text.<END>" + separator +
								"<PT0001>Text1<END>" + separator +
								"<PT0002>Text2<LINE>" + separator + "<END>" + separator +
								"<PT0003>Text3.<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void doesNotDumpPointersOutsideStartAndStopOffsets() throws IOException {
		File gamefile = new File("testFiles/gameTest/file2.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets;
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping text parameters. */
		Offset 	textStart = 	new Offset(12582918); //C00006
		Offset 	textStop = 		new Offset(12582925); //C0000D
		long 	header = 		0;
		long	textBlock =		12582912; // C00000
		
		/* Dumping pointer parameters */
		Offset pStart = new Offset(0); // 00
		Offset pStop = new Offset(8); // 08
		OffsetRangeGenerator gen = new OffsetRangeGenerator(pStart, pStop, 2, 0);
		PointerType pType = PointerType._2Byte_littleEndian;
		pOffsets = gen.getOffsets();
		
		String expectedResult = "<PT0003>Text2<LINE>" + separator + "<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void dumpsMultiplePointersAtSameOffset() throws IOException {
		File gamefile = new File("testFiles/gameTest/file2.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets;
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping text parameters. */
		Offset 	textStart = 	new Offset(12582896); //BFFFF0
		Offset 	textStop = 		new Offset(12582932); //C00014
		long 	header = 		0;
		long	textBlock =		12582912; // BF0000
		
		/* Dumping pointer parameters */
		Offset pStart = new Offset(0); // 00
		Offset pStop = new Offset(12); // 0C
		OffsetRangeGenerator gen = new OffsetRangeGenerator(pStart, pStop, 2, 0);
		PointerType pType = PointerType._2Byte_littleEndian;
		pOffsets = gen.getOffsets();
		
		String expectedResult = "A line of text.<END>" + separator +
								"<PT0002><PT0005><PT0006>Text1<END>" + separator +
								"<PT0003>Text2<LINE>" + separator + "<END>" + separator +
								"<PT0004>Text3.<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void canDumpZeroBytes() throws IOException {
		File gamefile = new File("testFiles/gameTest/file1.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(1); //0030
		Offset 	textStop = 		new Offset(1); //0057
		long 	header = 		10;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "";
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Check that file was created. */
		File script = new File(filePath);
		assertTrue(script.exists());
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	@Test
	public void canDumpZeroBytesWithPointers() throws IOException {
		File gamefile = new File("testFiles/gameTest/file1.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		File script = new File(filePath);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(1); //0030
		Offset 	textStop = 		new Offset(1); //0057
		long 	header = 		10;
		long	textBlock =		0;
		
		/* Dumping pointer parameters */
		Offset pStart = new Offset(0); // 00
		Offset pStop = new Offset(12); // 0C
		OffsetRangeGenerator gen = new OffsetRangeGenerator(pStart, pStop, 2, 0);
		PointerType pType = PointerType._2Byte_littleEndian;
		pOffsets = gen.getOffsets();
		
		String expectedResult = "";
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		assertTrue(script.exists());
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
		
	}
	
	@Test
	public void canDumpJapaneseCharacters() throws IOException {
		File gamefile = new File("testFiles/gameTest/file1.smc");
		JTableFile table = new JTableFile(
				new File("testFiles/testTableFiles/japanese.tbl"), "UTF-16");
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(22); //0016
		Offset 	textStop = 		new Offset(24); //0018
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		/* Separator added since the text read method adds one at the end of every line. */
		String expectedResult = "真真" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Check that file was created. */
		File script = new File(filePath);
		assertTrue(script.exists());
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-16");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	@Test
	public void canDumpHexadecimalValues() throws IOException {
		File gamefile = new File("testFiles/gameTest/file1.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(0);
		Offset 	textStop = 		new Offset(4);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "<$27><$24><$20><$23>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	@Test
	public void canDumpPointersLocatedInSeparateFile() throws IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		File pointerFile = new File("testFiles/gameTest/file2.smc");
		JTableFile table = new JTableFile(new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile, pointerFile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(0);
		Offset 	textStop = 		new Offset(10);
		long 	header = 		0;
		long	textBlock =		0;
		
		/* Dumping pointer parameters */
		Offset pStart = new Offset(2);
		Offset pStop = new Offset(6);
		OffsetRangeGenerator gen = new OffsetRangeGenerator(pStart, pStop, 2, 0);
		pOffsets = gen.getOffsets();
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "<PT0001>HejsaN<PT0002>ytt<$FF>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 0, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	/**
	 * Fixed length dumping tests starts here.
	 */
	
	
	
	@Test
	public void invalidatesNonModulusFixedLengthOffsets() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file1.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		ArrayList<ErrorReport> 	err = new ArrayList<ErrorReport>();
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(0);
		Offset 	textStop = 		new Offset(6);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		/* Dump file content to a textfile. */
		err = dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) 127);
		
		assertEquals(err.size(), 1);
	}
	
	@Test
	public void canDumpSingleStringWithoutPaddingBytes() throws IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(
			new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(0);
		Offset 	textStop = 		new Offset(5);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "Hejsa<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) 127);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	@Test
	public void canDumpSingleStringWithPaddingBytes() throws IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(
			new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(10);
		Offset 	textStop = 		new Offset(15);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "Fy<END>" + separator;
		int jo = (byte) Integer.parseInt("FF", 16);
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) jo);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void canDumpMultipleStringsWithPaddingBytes() throws IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(
			new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(0);
		Offset 	textStop = 		new Offset(20);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "Hejsa<END>" + separator +
								"Nytt<END>" + separator +
								"Fy<END>" + separator +
								"Hopp<END>"  + separator;
		int jo = (byte) Integer.parseInt("FF", 16);
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) jo);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	@Test
	public void canDumpMultipleStringsWithEndTagDespiteEndMissingInTableFile() throws IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(
			new File("testFiles/testTableFiles/ff3_only_upper_and_lower.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(0);
		Offset 	textStop = 		new Offset(20);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "Hejsa<END>" + separator +
								"Nytt<END>" + separator +
								"Fy<END>" + separator +
								"Hopp<END>"  + separator;
		int jo = (byte) Integer.parseInt("FF", 16);
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) jo);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	@Test
	public void canDumpStringsWithTerminatingByte() throws IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(
			new File("testFiles/testTableFiles/ff3_upper_lower_numbers_newline_end.tbl"));
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48);
		Offset 	textStop = 		new Offset(58);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "Apa<END>" + separator +
								"Nytta<END>" + separator;
		
		/* Dump file content to a textfile. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) 0);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void canDumpStringWithoutKowingTerminatingByteOrPaddedByte() throws IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48);
		Offset 	textStop = 		new Offset(53);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		String expectedResult = "<$20><$49><$3A><$00><$00><END>" + separator;
		
		/* Dump file content to a textfile. The byte 12 is not present in file. */
		dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) 12);
		
		/* Read content from file. */
		String dumpOutput = readScriptOutput("UTF-8");
		
		/* Compare content with expected output. */
		assertEquals(expectedResult, dumpOutput);
	}
	
	
	@Test
	public void TextStartNullValueThrowsException() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48);
		Offset 	textStop = 		new Offset(53);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		try {
			dumper.dump(null, textStop, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) 12);			
			fail("Should've thrown an IllegalArgumentException.");
		} catch(IllegalArgumentException e) {
			
		}
	}
	
	@Test
	public void TextStopNullValueThrowsException() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48);
		Offset 	textStop = 		new Offset(53);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		try {
			dumper.dump(textStart, null, header, pOffsets, pType, textBlock, table, filePath, 5, (byte) 12);			
			fail("Should've thrown an IllegalArgumentException.");
		} catch(IllegalArgumentException e) {
			
		}
	}
	
	@Test
	public void pointerOffsetsNullValueThrowsException() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48);
		Offset 	textStop = 		new Offset(53);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		try {
			dumper.dump(textStart, textStop, header, null, pType, textBlock, table, filePath, 5, (byte) 12);			
			fail("Should've thrown an IllegalArgumentException.");
		} catch(IllegalArgumentException e) {
			
		}
	}
	
	@Test
	public void pointerTypeNullValueThrowsException() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48);
		Offset 	textStop = 		new Offset(53);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		try {
			dumper.dump(textStart, textStop, header, pOffsets, null, textBlock, table, filePath, 5, (byte) 12);			
			fail("Should've thrown an IllegalArgumentException.");
		} catch(IllegalArgumentException e) {
			
		}
	}
	
	@Test
	public void tableNullValueThrowsException() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48);
		Offset 	textStop = 		new Offset(53);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		try {
			dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, null, filePath, 5, (byte) 12);			
			fail("Should've thrown an IllegalArgumentException.");
		} catch(IllegalArgumentException e) {
			
		}
	}
	
	@Test
	public void filePathNullValueThrowsException() throws FileNotFoundException, IOException {
		File gamefile = new File("testFiles/gameTest/file3.smc");
		JTableFile table = new JTableFile(null);
		
		ScriptDumper 			dumper = new JScriptDumper(gamefile);
		ArrayList<Offset>	 	pOffsets = new ArrayList<Offset>();
		String 					filePath = "testFiles/testScript.txt";
		
		/* Dumping parameters. */
		Offset 	textStart = 	new Offset(48);
		Offset 	textStop = 		new Offset(53);
		long 	header = 		0;
		long	textBlock =		0;
		PointerType pType = PointerType._2Byte_littleEndian;
		
		try {
			dumper.dump(textStart, textStop, header, pOffsets, pType, textBlock, table, null, 5, (byte) 12);			
			fail("Should've thrown an IllegalArgumentException.");
		} catch(IllegalArgumentException e) {
			
		}
	}
	
	
	
	@After
	public void close() {
		File testScript = new File(filePath);
		
		if (testScript.exists() && !testScript.delete()) {
			System.out.println("Could not delete temporary script file.");
		}
	}

	
	private String readScriptOutput(String charset) {
		StringBuilder text = new StringBuilder();
	    String NL = System.getProperty("line.separator");
	    Scanner scanner = null;
	    String TT;
	    try {
	    	scanner = new Scanner(new FileInputStream(filePath), charset);

	    	while (scanner.hasNextLine()){
	    		TT = scanner.nextLine();
	    		text.append(TT + NL);
	    	}

	    	
	    } catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    finally{
	    	if (scanner != null) {
	    		scanner.close();
	    	}
	    }
	    return text.toString();
	}
}
